{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "原文代码作者：https://github.com/wzyonggege/statistical-learning-method"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第6章 逻辑斯谛回归"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "LR是经典的分类方法\n",
    "\n",
    "\n",
    "回归模型：$f(x) = \\frac{1}{1+e^{-wx}}$\n",
    "\n",
    "其中wx线性函数：$wx =w_0*x_0 + w_1*x_1 + w_2*x_2 +...+w_n*x_n,(x_0=1)$\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from math import exp\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "from sklearn.datasets import load_iris\n",
    "from sklearn.model_selection import train_test_split"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 创建数据集，采用鸢尾花数据集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def create_data():\n",
    "    iris = load_iris()\n",
    "    df = pd.DataFrame(iris.data, columns=iris.feature_names)\n",
    "    df['label'] = iris.target\n",
    "    df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']\n",
    "    # 取前100条数据\n",
    "    data = np.array(df.iloc[:100, [0,1,-1]])\n",
    "    return data[:,:2], data[:,-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 加载数据集，并进行数据分割，70%的训练集和30%的测试集\n",
    "X, y = create_data()\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 逻辑斯蒂回归模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "class LogisticReressionClassifier:\n",
    "    def __init__(self, max_iter=200, learning_rate=0.01):\n",
    "        # 最大迭代次数\n",
    "        self.max_iter = max_iter\n",
    "        # 学习率\n",
    "        self.learning_rate = learning_rate\n",
    "    \n",
    "    # sigmoid函数：x>0为1，x<0为0，为逻辑斯蒂回归模型\n",
    "    def sigmoid(self, x):\n",
    "        return 1 / (1 + exp(-x))\n",
    "    \n",
    "    # 将X里面的每一个数组前面都添加1.0这个元素\n",
    "    def data_matrix(self, X):\n",
    "        data_mat = []\n",
    "        for d in X:\n",
    "            data_mat.append([1.0, *d])\n",
    "        return data_mat\n",
    "\n",
    "    # 训练函数\n",
    "    def fit(self, X, y):\n",
    "        # 向X矩阵的每一列向量都添加第一个元素1.0\n",
    "        data_mat = self.data_matrix(X)\n",
    "        # 初始化权重向量\n",
    "        self.weights = np.zeros((len(data_mat[0]),1), dtype=np.float32)\n",
    "        \n",
    "        for iter_ in range(self.max_iter):\n",
    "            # 对X中的每个向量进行迭代\n",
    "            for i in range(len(X)):\n",
    "                # 计算概率\n",
    "                result = self.sigmoid(np.dot(data_mat[i], self.weights))\n",
    "                # 计算与真实值的误差\n",
    "                error = y[i] - result\n",
    "                # 修正权重\n",
    "                self.weights += self.learning_rate * error * np.transpose([data_mat[i]])\n",
    "        print('LogisticRegression Model(learning_rate={},max_iter={})'.format(self.learning_rate, self.max_iter))\n",
    "    \n",
    "    # 计算正确率（即ROC值）\n",
    "    def score(self, X_test, y_test):\n",
    "        right = 0\n",
    "        X_test = self.data_matrix(X_test)\n",
    "        for x, y in zip(X_test, y_test):\n",
    "            result = np.dot(x, self.weights)\n",
    "            if (result > 0 and y == 1) or (result < 0 and y == 0):\n",
    "                right += 1\n",
    "        return right / len(X_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练模型并交叉验证"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "LogisticRegression Model(learning_rate=0.01,max_iter=200)\n"
     ]
    }
   ],
   "source": [
    "# 训练模型\n",
    "lr_clf = LogisticReressionClassifier()\n",
    "lr_clf.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.0"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 用测试集交叉验证模型\n",
    "lr_clf.score(X_test, y_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 绘制数据集，并画出回归模型的边界曲线"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x1a889080>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "x_ponits = np.arange(4, 8)\n",
    "y_ = -(lr_clf.weights[1]*x_ponits + lr_clf.weights[0])/lr_clf.weights[2]\n",
    "plt.plot(x_ponits, y_)\n",
    "\n",
    "plt.scatter(X[:50,0],X[:50,1], label='0')\n",
    "plt.scatter(X[50:,0],X[50:,1], label='1')\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "## sklearn\n",
    "\n",
    "### sklearn.linear_model.LogisticRegression\n",
    "\n",
    "solver参数决定了我们对逻辑回归损失函数的优化方法，有四种算法可以选择，分别是：\n",
    "- a) liblinear：使用了开源的liblinear库实现，内部使用了坐标轴下降法来迭代优化损失函数。\n",
    "- b) lbfgs：拟牛顿法的一种，利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。\n",
    "- c) newton-cg：也是牛顿法家族的一种，利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。\n",
    "- d) sag：即随机平均梯度下降，是梯度下降法的变种，和普通梯度下降法的区别是每次迭代仅仅用一部分的样本来计算梯度，适合于样本数据多的时候。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LogisticRegression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 设置分类器的参数\n",
    "clf = LogisticRegression(max_iter=200)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "E:\\DevSoft\\Python\\Python37\\lib\\site-packages\\sklearn\\linear_model\\logistic.py:433: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n",
      "  FutureWarning)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,\n",
       "          intercept_scaling=1, max_iter=200, multi_class='warn',\n",
       "          n_jobs=None, penalty='l2', random_state=None, solver='warn',\n",
       "          tol=0.0001, verbose=0, warm_start=False)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 训练模型\n",
    "clf.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.0"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 测试集交叉验证\n",
    "clf.score(X_test, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1.9271587  -3.16719941]] [-0.50966874]\n"
     ]
    }
   ],
   "source": [
    "print(clf.coef_, clf.intercept_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x1bae2470>"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "x_ponits = np.arange(4, 8)\n",
    "y_ = -(clf.coef_[0][0]*x_ponits + clf.intercept_)/clf.coef_[0][1]\n",
    "plt.plot(x_ponits, y_)\n",
    "\n",
    "plt.plot(X[:50, 0], X[:50, 1], 'bo', color='blue', label='0')\n",
    "plt.plot(X[50:, 0], X[50:, 1], 'bo', color='orange', label='1')\n",
    "plt.xlabel('sepal length')\n",
    "plt.ylabel('sepal width')\n",
    "plt.legend()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.2"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": false,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
